package org.embulk.plugin; import com.google.inject.Binder; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.name.Names; import com.google.inject.name.Named; import com.google.common.base.Preconditions; import org.embulk.spi.InputPlugin; import org.embulk.spi.FileInputPlugin; import org.embulk.spi.FileInputRunner; import org.embulk.spi.OutputPlugin; import org.embulk.spi.FileOutputPlugin; import org.embulk.spi.FileOutputRunner; /** * InjectedPluginSource loads plugins bound by Guice. * This plugin source is intended to be used in test cases. * Plugins need to be bound to Binder following: * * // Module * public void configure(Binder binder) * { * InjectedPluginSource.registerPluginTo(InputPluginclass, "my", MyInputPlugin.class); * } * */ public class InjectedPluginSource implements PluginSource { private final Injector injector; @Inject public InjectedPluginSource(Injector injector) { this.injector = injector; } public static interface PluginFactory <T> { public T newPlugin(Injector injector); } public <T> T newPlugin(Class<T> iface, PluginType type) throws PluginSourceNotMatchException { String name = type.getName(); try { @SuppressWarnings("unchecked") PluginFactory<T> factory = (PluginFactory<T>) injector.getInstance( Key.get(PluginFactory.class, pluginFactoryName(iface, name))); return factory.newPlugin(injector); } catch (com.google.inject.ConfigurationException ex) { throw new PluginSourceNotMatchException(); } } public static <T> void registerPluginTo(Binder binder, Class<T> iface, String name, final Class<?> impl) { PluginFactory<T> factory; if (FileInputPlugin.class.isAssignableFrom(impl)) { Preconditions.checkArgument(InputPlugin.class.equals(iface)); factory = new PluginFactory<T>() { @SuppressWarnings("unchecked") public T newPlugin(Injector injector) { return (T) new FileInputRunner((FileInputPlugin) injector.getInstance(impl)); } }; } else if (FileOutputPlugin.class.isAssignableFrom(impl)) { Preconditions.checkArgument(OutputPlugin.class.equals(iface)); factory = new PluginFactory<T>() { @SuppressWarnings("unchecked") public T newPlugin(Injector injector) { return (T) new FileOutputRunner((FileOutputPlugin) injector.getInstance(impl)); } }; } else { Preconditions.checkArgument(iface.isAssignableFrom(impl)); factory = new PluginFactory<T>() { @SuppressWarnings("unchecked") public T newPlugin(Injector injector) { return (T) injector.getInstance(impl); } }; } binder.bind(PluginFactory.class).annotatedWith(pluginFactoryName(iface, name)).toInstance(factory); } private static Named pluginFactoryName(Class<?> iface, String name) { return Names.named(iface.getName() + "." + name); } }